﻿/****************************************************************************
Copyright (c) 2014-2015 凌惊雪 微信:Lingjingxue 邮箱:lingjingxue@sina.com QQ:271487457

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/

using ServerBase.IniFile;
using UtilPublic.ServerLoger;
using ServerPublic.Manager;
using ServerGame.GameObject;
using System;
using System.Collections.Generic;
using UtilLib;
using ServerPublic.Data;
using ServerGame.Manager;
using ServerGame.Data;

namespace ServerGame.Service
{
    /// <summary>
    /// 玩家心跳
    /// </summary>
    public static partial class LoopPlayer
    {
        #region 注册
        public static void LoopPlayerRegister()
        {
            //ListSecond
            //ListSecond.TryAdd((Player p) => { loger.Warn($"玩家秒更新"); });

            //ListSecond10
            //推送走马灯
            ListSecond10.TryAdd(NoticeMgr.PushNoticeRolling);

            //ListMinute
            //检查新的全局邮件
            ListMinute.TryAdd(MailMgr.LoopPlayerMinite1);
            ListMinute.TryAdd(CharMgr.LoopPlayerMinite1);

            //ListMinute3
            //ListMinute3.TryAdd(xxx);

            //ListMinute5
            //ListMinute5.TryAdd(xxx);

            //ListMinute30
            //ListMinute30.TryAdd(xxx);

            //ListHour
            //邮件小时更新
            ListHour.TryAdd(MailMgr.LoopPlayerHour1);

            //ListOClockXX
            //ListOClockXX.TryAdd(xxx);

            //ListOClock0
            //ListOClock0.TryAdd(xxx);

            //ListOClock5
            //ListOClock5.TryAdd(xxx);

            //ListWeek
            //ListWeek.TryAdd(xxx);

            //ListMonth
            //ListMonth.TryAdd(xxx);
        }
        #endregion

        #region 临时数据
        //注册列表
        public static List<Action<Player>> ListSecond = new List<Action<Player>>();
        public static List<Action<Player>> ListSecond10 = new List<Action<Player>>();

        public static List<Action<Player>> ListMinute = new List<Action<Player>>();
        public static List<Action<Player>> ListMinute3 = new List<Action<Player>>();
        public static List<Action<Player>> ListMinute5 = new List<Action<Player>>();
        public static List<Action<Player>> ListMinute30 = new List<Action<Player>>();

        public static List<Action<Player>> ListHour = new List<Action<Player>>();

        public static List<Action<Player>> ListOClockXX = new List<Action<Player>>();
        public static List<Action<Player>> ListOClock0 = new List<Action<Player>>();
        public static List<Action<Player>> ListOClock5 = new List<Action<Player>>();

        public static List<Action<Player>> ListWeek = new List<Action<Player>>();
        public static List<Action<Player>> ListMonth = new List<Action<Player>>();
        #endregion

        /// <summary>
        /// 玩家心跳
        /// </summary>
        public static void LoopAllPlayerSecond()
        {
            foreach (var p in DataGame.DictPlayerOnline.Values)
            {
                LoopPlayerSecond(p);
            }
        }
        /// <summary>
        /// 玩家心跳 10秒一次
        /// </summary>
        public static void LoopAllPlayerSecond10()
        {
            foreach (var p in DataGame.DictPlayerOnline.Values)
            {

                LoopPlayerSecond10(p);
            }
        }

        /// <summary>
        /// 秒心跳
        /// </summary>
        public static void LoopPlayerSecond(Player player, bool bInitPlayer = false)
        {
            player.InitLoop();

            //秒更新
            PlayerUpdateSecond(player);
        }

        /// <summary>
        /// 10秒心跳
        /// </summary>
        public static void LoopPlayerSecond10(Player player, bool bInitPlayer = false)
        {
            player.InitLoop();

            //10秒更新
            PlayerUpdateSecond10(player);

            //日零点更新
            PlayerUpdateDayZeroOClock(player);

            //日五点更新
            PlayerUpdateDayFiveOClock(player);

            //日小时更新
            PlayerUpdateDayXXOClock(player, bInitPlayer);

            //周零点更新
            PlayerUpdateWeekZeroOClock(player);

            //月零点更新
            PlayerUpdateMonthZeroOClock(player);

            //分钟更新 1
            PlayerUpdateMinute1(player);

            //分钟更新 3
            PlayerUpdateMinute3(player);

            //分钟更新 5
            PlayerUpdateMinute5(player);

            //分钟更新 30
            PlayerUpdateMinute30(player);

            //小时更新 1
            PlayerUpdateHour1(player);

            //临时数据更新
            PlayerUpdateTemp(player);
        }

        /// <summary>
        /// 玩家零点更新
        /// </summary>
        /// <param name="player"></param>
        public static void PlayerUpdateDayZeroOClock(Player player)
        {
            var timeKey = EDataLoopDtKey.日零点更新;
            if (!player.TimeLoop.SameDay(player.DaLoop.GetLoopDatetime(timeKey)))
            {
                loger.Debug($"PlayerUpdateDayZeroOClock player:{player.Uid}");
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListOClock0) { item(player); }

            }
        }

        /// <summary>
        /// 玩家五点更新
        /// </summary>
        /// <param name="player"></param>
        public static void PlayerUpdateDayFiveOClock(Player player)
        {
            var timeKey = EDataLoopDtKey.日五点更新;
            if (!(player.TimeLoop.AddHours(-5)).SameDay(player.DaLoop.GetLoopDatetime(timeKey).AddHours(-5)))
            {
                loger.Debug($"PlayerUpdateDayFiveOClock player:{player.Uid}");
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListOClock5) { item(player); }
            }
        }

        /// <summary>
        /// 玩家小时更新
        /// </summary>
        /// <param name="player"></param>
        public static void PlayerUpdateDayXXOClock(Player player, bool bInitPlayer = false)
        {
            if (true)
            {
                //日0 6 12 18点更新
                var dtNow = player.TimeLoop;
                bool brefresh = false;
                var listscale = new List<int>() { 0, 6, 12, 18 };
                var timeKey = EDataLoopDtKey.日X点更新;
                foreach (var nn in listscale)
                {
                    if (dtNow.SameDay(player.DaLoop.GetLoopDatetime(timeKey)))
                    {
                        if (dtNow.Hour >= nn && dtNow.Hour != player.DaLoop.GetLoopDatetime(timeKey).Hour)
                        {
                            brefresh = true;
                        }
                    }
                    else
                    {
                        if (dtNow.Hour >= nn)
                        {
                            brefresh = true;
                        }
                    }
                }
                if (brefresh)
                {
                    loger.Debug($"PlayerUpdateDayXXOClock player:{player.Uid}");
					
                    //设置了重置时间
                    player.DaLoop.SetLoopDatetime(timeKey, dtNow);

                    foreach (var item in ListOClockXX) { item(player); }
                }
            }
        }

        /// <summary>
        /// 玩家每周零点更新
        /// </summary>
        /// <param name="player"></param>
        public static void PlayerUpdateWeekZeroOClock(Player player)
        {
            var timeKey = EDataLoopDtKey.周零点更新;
            if (!player.TimeLoop.SameWeek(player.DaLoop.GetLoopDatetime(timeKey), true))
            {
                loger.Debug($"PlayerUpdateWeekZeroOClock player:{player.Uid}");

                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListWeek) { item(player); }
            }
        }

        /// <summary>
        /// 玩家每月零点更新
        /// </summary>
        /// <param name="player"></param>
        public static void PlayerUpdateMonthZeroOClock(Player player)
        {
            var timeKey = EDataLoopDtKey.月零点更新;
            if (!player.TimeLoop.SameMonth(player.DaLoop.GetLoopDatetime(timeKey)))
            {
                loger.Debug($"PlayerUpdateMonthZeroOClock player:{player.Uid}");

                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListMonth) { item(player); }
            }
        }

        // 秒更新
        public static void PlayerUpdateSecond(Player player)
        {
            var timeKey = EDataLoopDtKey.秒更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            long count = (long)(ts.TotalSeconds);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListSecond) { item(player); }
            }
        }
        // 10秒更新
        public static void PlayerUpdateSecond10(Player player)
        {
            var timeKey = EDataLoopDtKey.十秒更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            long count = (long)(ts.TotalSeconds);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListSecond10) { item(player); }
            }
        }
        // 分钟更新 1
        public static void PlayerUpdateMinute1(Player player)
        {
            var timeKey = EDataLoopDtKey.一分钟更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            int count = (int)(ts.TotalMinutes);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListMinute) { item(player); }
            }
        }
        // 分钟更新 3
        public static void PlayerUpdateMinute3(Player player)
        {
            var timeKey = EDataLoopDtKey.三分钟更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            int count = (int)(ts.TotalMinutes / 3);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListMinute3) { item(player); }
            }
        }
        // 分钟更新 5
        public static void PlayerUpdateMinute5(Player player)
        {
            var timeKey = EDataLoopDtKey.五分钟更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            int count = (int)(ts.TotalMinutes / 5);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListMinute5) { item(player); }
            }
        }
        // 分钟更新 30
        public static void PlayerUpdateMinute30(Player player)
        {
            var timeKey = EDataLoopDtKey.三十分钟更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            int count = (int)(ts.TotalMinutes / 30);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListMinute30) { item(player); }
            }
        }
        // 小时更新 1
        public static void PlayerUpdateHour1(Player player)
        {
            var timeKey = EDataLoopDtKey.一小时更新;
            var ts = player.TimeLoop - player.DaLoop.GetLoopDatetime(timeKey);
            int count = (int)(ts.TotalHours / 1);
            if (count > 0)
            {
                //设置了重置时间
                player.DaLoop.SetLoopDatetime(timeKey, player.TimeLoop);

                foreach (var item in ListHour) { item(player); }
            }
        }
        // 临时数据更新
        public static void PlayerUpdateTemp(Player player)
        {
            ////半小时存一次档
            //TimeSpan tsSave = DateTime.Now - player.TimeLastAutoSave;
            //if (tsSave.Minutes >= 5)
            //{
            //    player.AutoSave();
            //    player.TimeLastAutoSave = DateTime.Now;
            //}
        }


        #region Dump
        public static void Dump()
        {
            Dump(ListSecond);
            Dump(ListSecond10);
            Dump(ListMinute);
            Dump(ListMinute3);
            Dump(ListMinute5);
            Dump(ListMinute30);
            Dump(ListHour);
            Dump(ListOClockXX);
            Dump(ListOClock0);
            Dump(ListOClock5);
            Dump(ListWeek);
            Dump(ListMonth);
        }
        public static void Dump(List<Action<Player>> list)
        {
            foreach (var item in list)
            {
                loger.Debug($"{item.Method} {item.Method}");
            }
        } 
        #endregion

    }
}